// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose:  Definition of CUpdateChecker class..
//   $Id$


#include "stdafx.h"
#include "UpdateChecker.h"
#include <Common/Internet/msw/InternetUtils.h>
#include <wininet.h>
#include <msxml6.h>

static const char *gc_sUpdateFilePath = "http://www.formsplayer.com/files/releases/formsplayer-pad.xml";
static const char *gc_sApplicationName = "formsPlayer";
static const char *gc_sWhitespace = " ";
const CComBSTR gc_sPADVersionXPath = L"/XML_DIZ_INFO/Program_Info[Program_Name = 'formsPlayer']/Program_Version";

// Construction.
CUpdateChecker::CUpdateChecker()
:m_bInitialised(false), m_bUpdatesAvailable(false), m_bInstallationInProgress(false)
{
}

// Destruction.
CUpdateChecker::~CUpdateChecker()
{
}

// Initialisation.
HRESULT CUpdateChecker::Initialise(BSTR sCurrentVersion)
{
	HRESULT hr = S_OK;

	if(!m_bInitialised) {
		if(sCurrentVersion) {
			m_sCurrentVersion = sCurrentVersion;
			m_bInitialised = true;
		} else
			hr = E_INVALIDARG;
	} else
		hr = S_FALSE;

	return hr;
}

// Check for updates.
HRESULT CUpdateChecker::CheckForUpdates(void)
{
	HRESULT hr = S_OK;

	// Check that we've been initialised.
	if(m_bInitialised) {
		DWORD dwThreadId = 0;
		CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadCheckForUpdates, this, 0, &dwThreadId);
	} else
		hr = E_PENDING;

	return hr;
}

DWORD WINAPI CUpdateChecker::ThreadCheckForUpdates(LPVOID pParameter)
{
	try {
		if(pParameter && IsInternetConnectionOpen()) {
			BSTR sCurrentVersion = reinterpret_cast<BSTR>(pParameter);
			char *sUserAgent = new char[strlen(gc_sApplicationName) + strlen(gc_sWhitespace) + wcslen(sCurrentVersion) + 1];
			sprintf(sUserAgent, "%s%s%S", gc_sApplicationName, gc_sWhitespace, sCurrentVersion);

			void *pPAD = 0;
			DWORD dwPADLength = 0;
			if(SUCCEEDED(xport::ReadFromInternet(gc_sUpdateFilePath, &pPAD, dwPADLength, sUserAgent)) && pPAD && dwPADLength > 0) {
				CComBSTR sPAD;
				if(IsDataUnicode(pPAD)) {
					pPAD = reinterpret_cast<char *>(pPAD) + 2;
					CComBSTR sTemp((dwPADLength - 1)/ sizeof(wchar_t), reinterpret_cast<wchar_t *>(pPAD));
					sPAD.Attach(sTemp.Detach());
				} else {
					CComBSTR sTemp(dwPADLength / sizeof(char), reinterpret_cast<char *>(pPAD));
					sPAD.Attach(sTemp.Detach());
				}

				if(sPAD.Length() > 0) {
					CComPtr<IXMLDOMDocument> pPADDOM;
					pPADDOM.CoCreateInstance(CLSID_DOMDocument60);
					if(pPADDOM) {
						VARIANT_BOOL bLoaded = VARIANT_FALSE;
						pPADDOM->loadXML(sPAD, &bLoaded);
						if(bLoaded == VARIANT_TRUE) {
							CComPtr<IXMLDOMNode> pVersionNode;
							pPADDOM->selectSingleNode(gc_sPADVersionXPath, &pVersionNode);
							CComQIPtr<IXMLDOMElement> pVersionElement = pVersionNode;
							if(pVersionElement) {
								CComBSTR sLatestVersion;
								pVersionElement->get_text(&sLatestVersion);
								if(IsVersionOlder(sCurrentVersion, sLatestVersion)) {
									// TODO: Implement a smooth upgrade process for this case.
									CString sMessage;
									sMessage.Format(_T("A new version of formsPlayer is available, containing a number of new features, bug fixes and performance improvements. The free upgrade, along with full details of what has changed, is available on the formsPlayer website: http://www.formsplayer.com/\n\nInstalled formsPlayer version: %s\nLatest stable version: %s"), CW2T(sCurrentVersion), CW2T(sLatestVersion.m_str));
									::MessageBox(0, sMessage, _T("Upgrade formsPlayer!"), MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND);
								}
							}
						}
					}
				}
			}
		}
	}
	catch(...) {
	}

	return 0;
}

// Download and install updates, pending agreement from the user
HRESULT CUpdateChecker::RequestInstall(void)
{
	return E_NOTIMPL;
}
